home *** CD-ROM | disk | FTP | other *** search
/ United Public Domain Gold 2 / United Public Domain Gold 2.iso / utilities / pu248.dms / pu248.adf / Intuition / FileWindow / FileWindow.c < prev    next >
Text File  |  1992-05-01  |  78KB  |  2,473 lines

  1. /***********************************************************/
  2. /*                                                         */
  3. /* Amiga C Encyclopedia (ACE) V3.0      Amiga C Club (ACC) */
  4. /* -------------------------------      ------------------ */
  5. /*                                                         */
  6. /* Book:    ACM Intuition               Amiga C Club       */
  7. /* Chapter: FileWindow                  Tulevagen 22       */
  8. /* File:    FileWindow.c                181 41  LIDINGO    */
  9. /* Author:  Anders Bjerin               SWEDEN             */
  10. /* Date:    92-05-01                                       */
  11. /* Version: 1.30                                           */
  12. /*                                                         */
  13. /*   Copyright 1992, Anders Bjerin - Amiga C Club (ACC)    */
  14. /*                                                         */
  15. /* Registered members may use this program freely in their */
  16. /*     own commercial/noncommercial programs/articles.     */
  17. /*                                                         */
  18. /***********************************************************/
  19.  
  20.  
  21.  
  22. /*  FFFFF III L     EEEEE     W     W III N   N DDD    OOO  W     W          */
  23. /*  F      I  L     E         W     W  I  NN  N D  D  O   O W     W          */
  24. /*  FFFF   I  L     EEE       W  W  W  I  N N N D   D O   O W  W  W          */
  25. /*  F      I  L     E          W W W   I  N  NN D  D  O   O  W W W           */
  26. /*  F     III LLLLL EEEEE       W W   III N   N DDD    OOO    W W            */
  27. /*                                                                           */
  28. /*                                                                           */
  29. /*  FILE WINDOW   VERSION 1.30   92-03-06                                    */
  30. /*                                                                           */
  31. /*  FILE WINDOW was created by Anders Bjerin, and is distributed as          */
  32. /*  public domain with NO RIGHTS RESERVED. That means that you can do        */
  33. /*  what ever you want with the program.                                     */
  34. /*                                                                           */
  35. /*  You may use FILE WINDOW in your own programs, commercial or not, and     */
  36. /*  do not even need to mention that you have used it. You may alter the     */
  37. /*  source code to fit your needs, and you may spread it to anyone.          */
  38. /*                                                                           */
  39. /*                                                                           */
  40. /*                                                                           */
  41. /*  The reason why I created FILE WINDOW was that I never more wanted to     */
  42. /*  see that old stupid "Please type in filename:" prompt. It is a disgrace  */
  43. /*  for any program to use it, and VERY annoying for the user.               */
  44. /*                                                                           */
  45. /*  REMEMBER, one of the first things the user will see of your program is   */
  46. /*  the file requester. If you want your program to make a good impression,  */
  47. /*  and look solid, I would recommend you to use a good file requester.      */
  48. /*                                                                           */
  49. /*  FILE WINDOW is written to be as easy as possible to use, and is fully    */
  50. /*  amigaized. It is similar to other good file requesters, but has several  */
  51. /*  advantages:                                                              */
  52. /*                                                                           */
  53. /*   1. FILE WINDOW dynamically allocates memory for each file. That means   */
  54. /*      that there is no memory wasted as it would have been if you had      */
  55. /*      statically allocated the filenames in arrays. It also means that the */
  56. /*      memory is the only limitation on how many files the program can      */
  57. /*      display.                                                             */
  58. /*                                                                           */
  59. /*   2. While FILE WINDOW is reading the directories, it is still obeying    */
  60. /*      your commands. You may change directory, type in the file name       */
  61. /*      yourself etc etc while the program still is working. All of us know  */
  62. /*      how irritating it is to see the little Zzz pointer in a program      */
  63. /*      while the disk is examined. This is especially annoying when you     */
  64. /*      KNOW the filename, and only want to type it in.                      */
  65. /*                                                                           */
  66. /*   3. FILE WINDOW was written for the Amiga. It uses boolean, string and   */
  67. /*      proportional gadgets, and is using them as recommended. For example, */
  68. /*      the proportional gadget's knob changes size corresponding to how     */
  69. /*      many files/directories there are. (It is strange that there are      */
  70. /*      several file requesters using a static small knob instead. That      */
  71. /*      makes it much harder for the user to see how many files there are in */
  72. /*      the directory.)                                                      */
  73. /*                                                                           */
  74. /*   4. There are three boolean gadgets which allows the user to quickly     */
  75. /*      select df0:, df1: and dh0:.                                          */
  76. /*                                                                           */
  77. /*   5. FILE WINDOW has a boolean gadget "<" which steps back one directory  */
  78. /*      each time it is pressed. (Same as "/ Parent dir")                    */
  79. /*                                                                           */
  80. /*   6. You can specify a file-extension, and only the files with that       */
  81. /*      extension will be displayed. (Directories are always showed.)        */
  82. /*      The user can also change the extension since it is a string gadget.  */
  83. /*      (If there are any characters in the string gadget, the text "Ext:"   */
  84. /*      will be highlighted to tell the user that EXTENSION MODE is on.)     */
  85. /*                                                                           */
  86. /*   7. The files/directories are automatically sorted alphabetically while  */
  87. /*      they are taken from the disk. Directories first, highlighted with    */
  88. /*      the ending (Dir), and then the files.                                */
  89. /*                                                                           */
  90. /*   8. FILE WINDOW deallocates all memory allocated, and is fool proof. If  */
  91. /*      something goes wrong (not enough memory, wrong directory name etc),  */
  92. /*      the program will open a requester and tell the user what the         */
  93. /*      problem is.                                                          */
  94. /*                                                                           */
  95. /*   9. The source code is distributed with the program so you can alter it  */
  96. /*      to fit your needs.                                                   */
  97. /*                                                                           */
  98. /*  10. FILE WINDOW is not as a normal file requester, since it uses a       */
  99. /*      (surprise, surprise) window instead of a requester to display the    */
  100. /*      files on. That means that the calling program does not need to       */
  101. /*      have a window itself, to be able to use FILE WINDOW. (A normal       */
  102. /*      requester always needs a pointer to a window.)                       */
  103. /*                                                                           */
  104. /*  11. There are no Image structures in the code, so FILE WINDOW does not   */
  105. /*      need to be in the CHIP memory.                                       */
  106. /*                                                                           */
  107. /*  12. The width of the window is 320, which means that any program can use */
  108. /*      it, both in High as well as Low resolution.                          */
  109. /*                                                                           */
  110. /*  13. When FILE WINDOW has examined all files in the directory, the        */
  111. /*      program is put to sleep. That will speed up other programs, and      */
  112. /*      will not use unnecessary processing time.                            */
  113. /*                                                                           */
  114. /*  14. Fast updating of the display.                                        */
  115. /*                                                                           */
  116. /*  15. FILE WINDOW was created by Anders Bjerin.                            */
  117. /*                                                                           */
  118. /*                                                                           */
  119. /*                                                                           */
  120. /*  FILE WINDOW is very easy to install in your program, and I have even     */
  121. /*  done an example on how to use it. The source code is full of comments    */
  122. /*  to make it easier for you to change something in the program, but        */
  123. /*  if you would have any problems, feel free to contact me.                 */
  124. /*                                                                           */
  125. /*                                                                           */
  126. /*  FILE WINDOW will look something like this when you run it:               */
  127. /*                                                                           */
  128. /*  -----------------------------------                                      */
  129. /*  |#| TITLE                   |==|==|                                      */
  130. /*  |---------------------------------|                                      */
  131. /*  | df0: | df1: | dh0: | Ext:XXXXXX |                                      */
  132. /*  |---------------------------------|                                      */
  133. /*  | Drawer: XXXXXXXXXXXXXXXXXXXX |<<|                                      */
  134. /*  |---------------------------------|                                      */
  135. /*  |                              |XX|                                      */
  136. /*  |        FILE DISPLAY          |XX|                                      */
  137. /*  |                              |XX|                                      */
  138. /*  |                              |XX|                                      */
  139. /*  |                              |XX|                                      */
  140. /*  |                              |OO|                                      */
  141. /*  |                              |OO|                                      */
  142. /*  |                              |OO|                                      */
  143. /*  |---------------------------------|                                      */
  144. /*  | File: XXXXXXXXXXXXXXXXXXXXXXXXX |                                      */
  145. /*  |---------------------------------|                                      */
  146. /*  | LOAD | SAVE | DELETE | CANCEL | |                                      */
  147. /*  -----------------------------------                                      */
  148. /*                                                                           */
  149. /*                                                                           */
  150. /*                                                                           */
  151. /*  FFFFF III L     EEEEE     W     W III N   N DDD    OOO  W     W          */
  152. /*  F      I  L     E         W     W  I  NN  N D  D  O   O W     W          */
  153. /*  FFFF   I  L     EEE       W  W  W  I  N N N D   D O   O W  W  W          */
  154. /*  F      I  L     E          W W W   I  N  NN D  D  O   O  W W W           */
  155. /*  F     III LLLLL EEEEE       W W   III N   N DDD    OOO    W W            */
  156. /*                                                                           */
  157. /*  III N   N FFFFF  OOO  RRRR  M   M  AAA  TTTTTTT III  OOO  N   N          */
  158. /*   I  NN  N F     O   O R   R MM MM A   A    T     I  O   O NN  N          */
  159. /*   I  N N N FFF   O   O RRRR  M M M AAAAA    T     I  O   O N N N          */
  160. /*   I  N  NN F     O   O R  R  M   M A   A    T     I  O   O N  NN          */
  161. /*  III N   N F      OOO  R   R M   M A   A    T    III  OOO  N   N          */
  162. /*                                                                           */
  163. /*                                                                           */
  164. /*  operation=FileWindow( title, extension, x, y, screen, file );            */
  165. /*                                                                           */
  166. /*  operation: a variable which will contain the "flags" FILE WINDOW         */
  167. /*             returned.                                                     */
  168. /*  title:     string containing the name of the FILE WINDOW.                */
  169. /*  extension: string to be used as a file extension.                        */
  170. /*  x:         x position of the FILE WINDOW.                                */
  171. /*  y:         y position of the FILE WINDOW.                                */
  172. /*  screen:    pointer to a screen if there exist one.                       */
  173. /*  file:      a string which will contain the file name together with       */
  174. /*             the entire path. (For example: "df0:letters/payments.doc"     */
  175. /*                                                                           */
  176. /*                                                                           */
  177. /*  Title is a string which will appear on the drag gadget. Write NULL if    */
  178. /*  you do not want any string there.                                        */
  179. /*                                                                           */
  180. /*  Extension is a 7 character long string. 6 letters and the NULL ('\0')    */
  181. /*  sign. If you give FILE WINDOW a string, the program will only display    */
  182. /*  the files which endings match with your string. (Directories will always */
  183. /*  be displayed.) If you do not want to use a file extension you simply     */
  184. /*  write NULL.                                                              */
  185. /*                                                                           */
  186. /*  The width of the window is 320 pixels which means that if you are using  */
  187. /*  a low resolution display (320 pixels) x should be initialized to be 0.   */
  188. /*  If you are using a high resolution display (640 pixels) x can be         */
  189. /*  between 0 and 320.                                                       */
  190. /*                                                                           */
  191. /*  On a NTSC screen (200 lines) y can be between 0 and 37. On a PAL screen  */
  192. /*  (256 lines) between 0 and 93.                                            */
  193. /*                                                                           */
  194. /*  If your program is using a CUSTOM SCREEN you should give FILE WINDOW a   */
  195. /*  pointer to your screen. Otherwise, if you are using a WBENCH SCREEN you  */
  196. /*  simply write NULL.                                                       */
  197. /*                                                                           */
  198. /*  Name is a string which can already contain a file name with path if      */
  199. /*  you want. If the string is empty, FILE WINDOW will start to display the  */
  200. /*  current directory. When the user has selected the file to LOAD or SAVE   */
  201. /*  it is here you should look for the file name with path.                  */
  202. /*                                                                           */
  203. /*                                                                           */
  204. /*                                                                           */
  205. /*  For examples:                                                            */
  206. /*                                                                           */
  207. /*    1. operation=FileWindow( NULL, NULL, 0, 0, NULL, file);                */
  208. /*                                                                           */
  209. /*       operation has been declared as: USHORT operation;                   */
  210. /*       file has been declared as     : UBYTE file[TOTAL_LENGTH];           */
  211. /*                                                                           */
  212. /*                                                                           */
  213. /*    2. operation=FileWindow(title, ext, x, y, my_screen, file);            */
  214. /*                                                                           */
  215. /*       operation has been declared as: USHORT operation;                   */
  216. /*       title           -"-           : UBYTE title[ANY_LENGTH];            */
  217. /*       ext             -"-           : UBYTE ext[7];                       */
  218. /*       x, y            -"-           : SHORT x, y;                         */
  219. /*       my_screen       -"-           : struct Screen *my_screen;           */
  220. /*       file            -"-           : UBYTE file[TOTAL_LENGTH];           */
  221. /*                                                                           */
  222. /*                                                                           */
  223. /*  Remember to "include" the file "FileWindow.h"!                           */
  224. /*  ex: #include "FileWindow.h"                                              */
  225. /*                                                                           */
  226. /*  For more information see the file "Example.c".                           */
  227. /*                                                                           */
  228. /*  ENJOY YOUR AMIGA, AND MAKE EVERYONE ELSE ENJOY IT TOO!                   */
  229. /*                                                                           */
  230. /*  Anders Bjerin                                                            */
  231.  
  232.  
  233.  
  234. #include <exec/types.h>
  235. #include <exec/nodes.h>
  236. #include <exec/lists.h>
  237. #include <exec/libraries.h>
  238. #include <exec/ports.h>
  239. #include <exec/interrupts.h>
  240. #include <exec/io.h>
  241. #include <exec/memory.h>
  242. #include <libraries/dos.h>
  243. #include <libraries/dosextens.h>
  244. #include <intuition/intuition.h>
  245. #include <string.h>
  246.  
  247. #include "FileWindow.h"
  248.  
  249.  
  250.  
  251. /* Declare the functions we are going to use: */
  252. USHORT FileWindow();
  253. STRPTR right_pos();
  254. APTR save_file_info();
  255. BOOL file_comp();
  256. BOOL directory();
  257. BOOL last_check();
  258. BOOL new_drawer();
  259. BOOL pick_file();
  260. BOOL request_ask();
  261. void put_in();
  262. void deallocate_file_info();
  263. void change_device();
  264. void parent();
  265. void request_ok();
  266. void display_list();
  267. void connect_dir_file();
  268. void adjust_string_gadgets();
  269. void delete_file_dir();
  270.  
  271.  
  272.  
  273. extern struct IntuitionBase *IntuitionBase;
  274.  
  275. struct Window *file_window;
  276. struct IntuiMessage *my_gadget_message;
  277.  
  278.  
  279.  
  280. /* We will allocate memory, using this structure, for every file/    */
  281. /* directory we find. They will be linked to each otherer, in such a */
  282. /* way that all directories will come first (sorted alphabetically), */
  283. /* and after them will the files come (also sorted alphabetically).  */
  284. struct file_info
  285. {
  286.   BYTE name[28];          /* Name of the file/directory, 27 characters. */
  287.   BOOL directory;         /* If it is a directory.                      */
  288.   struct file_info *next; /* Pointer to the next file_info structure.   */
  289. };
  290.  
  291.  
  292. struct FileInfoBlock *file_info;
  293. struct FileLock *lock, *Lock();
  294.  
  295.  
  296. BOOL file_lock;  /* Have we locked a file?       */
  297. BOOL more_files; /* More files in the directory? */
  298. BOOL first_file; /* First file?                  */
  299.  
  300.  
  301. struct file_info *first_pointer; /* Pointing to the first structure. */
  302.  
  303.  
  304. /* The program will use a ROM-font, 80 characters wide (40 LOWRES). */
  305. /* This is to make sure that all the text will fit in nicely in the */
  306. /* window, even if the calling program is using another font.       */
  307. struct TextAttr my_font=
  308. {
  309.   "topaz.font", /* Font Name */
  310.   TOPAZ_EIGHTY, /* Font Height */
  311.   FS_NORMAL,    /* Style */
  312.   FPF_ROMFONT   /* Preferences */
  313. };
  314.  
  315.  
  316.  
  317.  
  318.  
  319. /* ********************************************************************* */
  320. /* * IntuiText structures for the requesters                           * */
  321. /* ********************************************************************* */
  322.  
  323.  
  324. struct IntuiText text_request=
  325. {
  326.   0, 2,                        /* FrontPen, BackPen */
  327.   JAM1,                        /* DrawMode */
  328.   15, 5,                       /* LewftEdge, TopEdge */
  329.   &my_font,                    /* *ITextFont */
  330.   NULL,                        /* *IText */
  331.   NULL                         /* *NextText */
  332. };
  333.  
  334.  
  335. struct IntuiText ok_request=
  336. {
  337.   0, 2,     /* FrontPen, BackPen */
  338.   JAM1,     /* DrawMode */
  339.   6, 3,     /* LewftEdge, TopEdge */
  340.   &my_font, /* *ITextFont */
  341.   "OK",     /* *IText */
  342.   NULL      /* *NextText */
  343. };
  344.  
  345.  
  346. struct IntuiText option1_request=
  347. {
  348.   0, 2,     /* FrontPen, BackPen */
  349.   JAM1,     /* DrawMode */
  350.   6, 3,     /* LewftEdge, TopEdge */
  351.   &my_font, /* *ITextFont */
  352.   NULL,     /* *IText */
  353.   NULL      /* *NextText */
  354. };
  355.  
  356.  
  357. struct IntuiText option2_request=
  358. {
  359.   0, 2,     /* FrontPen, BackPen */
  360.   JAM1,     /* DrawMode */
  361.   6, 3,     /* LewftEdge, TopEdge */
  362.   &my_font, /* *ITextFont */
  363.   NULL,     /* *IText */
  364.   NULL      /* *NextText */
  365. };
  366.  
  367.  
  368.  
  369.  
  370.  
  371.  
  372. /* Values for a 4-letter box: */
  373. SHORT points4[]=
  374. {
  375.    0,  0,
  376.   44,  0,
  377.   44, 14,
  378.    0, 14,
  379.    0,  0
  380. };
  381.  
  382.  
  383. /* Values for a 6-letter box: */
  384. SHORT points6[]=
  385. {
  386.    0,  0,
  387.   60,  0,
  388.   60, 14,
  389.    0, 14,
  390.    0,  0
  391. };
  392.  
  393.  
  394. /* A border for a 4-letter box: */
  395. struct Border border_text4=
  396. {
  397.   0, 0,         /* LeftEdge, TopEdge */
  398.   1, 2, JAM1,   /* FrontPen, BackPen, DrawMode */
  399.   5,            /* Count */
  400.   points4,      /* *XY */
  401.   NULL          /* *NextBorder */
  402. };
  403.  
  404.  
  405. /* A border for a 6-letter box: */
  406. struct Border border_text6=
  407. {
  408.   0, 0,         /* LeftEdge, TopEdge */
  409.   1, 2, JAM1,   /* FrontPen, BackPen, DrawMode */
  410.   5,            /* Count */
  411.   points6,      /* *XY */
  412.   NULL          /* *NextBorder */
  413. };
  414.  
  415.  
  416.  
  417. /* ********************************************************************* */
  418. /* * Information for the proportional gadget                           * */
  419. /* ********************************************************************* */
  420.  
  421. /* Since we are using the auto-knob we set GadgetRender to point to an   */
  422. /* Image. In this case we do not need to initialize the Image structure: */
  423. struct Image image_prop;
  424.  
  425. /* This is the special data required by the proportional gadget: */
  426. struct PropInfo prop_info=
  427. {
  428.   AUTOKNOB| /* We want to use the auto-knob. */
  429.   FREEVERT, /* The knob should move vertically. */
  430.   0,0,      /* HorizPot, VertPot: will be initialized later. */
  431.   0,        /* HorizBody                 -"-                 */
  432.   0xFFFF,   /* VertBody: No data to show, maximum. */
  433.   
  434.   0,0,0,0,0,0 /* Intuition sets and maintains these variables. */
  435. };
  436.  
  437. struct Gadget gadget_proportional=
  438. {
  439.   NULL,                     /* *NextGadget */
  440.   290, 50, 21, 72,          /* LeftEdge, TopEdge, Width, Height */
  441.   GADGHCOMP,                /* Flags */
  442.   GADGIMMEDIATE|FOLLOWMOUSE|RELVERIFY, /* Activation */
  443.   PROPGADGET,               /* GadgetType */
  444.   (APTR) &image_prop,       /* GadgetRender */
  445.   NULL,                     /* SelectRender */
  446.   NULL,                     /* *GadgetText */
  447.   NULL,                     /* MutualExclude */
  448.   (APTR) &prop_info,        /* SpecialInfo */
  449.   NULL,                     /* GadgetID */
  450.   NULL                      /* UserData */
  451. };
  452.  
  453.  
  454.  
  455. /* UndoBuffer for the string gadgets: */
  456. UBYTE name_backup[DRAWER_LENGTH];
  457.  
  458.  
  459.  
  460. /* ********************************************************************* */
  461. /* * Information for the string gadget "Drawer:"                       * */
  462. /* ********************************************************************* */
  463.  
  464. UBYTE drawer_name[DRAWER_LENGTH];
  465.  
  466. /* Values for a 28-letter string box: */
  467. SHORT points28s[]=
  468. {
  469.    -7, -4,
  470.   200, -4,
  471.   200, 11,
  472.    -7, 11,
  473.    -7, -4
  474. };
  475.  
  476.  
  477. /* A border for a 28-letter string box: */
  478. struct Border border_text28s=
  479. {
  480.   0, 0,         /* LeftEdge, TopEdge */
  481.   1, 2, JAM1,   /* FrontPen, BackPen, DrawMode */
  482.   5,            /* Count */
  483.   points28s,    /* *XY */
  484.   NULL          /* *NextBorder */
  485. };
  486.  
  487.  
  488. struct IntuiText text_drawer=
  489. {
  490.   1, 2,       /* FrontPen, BackPen */
  491.   JAM1,       /* DrawMode */
  492.   -69, 0,     /* LewftEdge, TopEdge */
  493.   &my_font,   /* *ITextFont */
  494.   "Drawer:",  /* *IText */
  495.   NULL        /* *NextText */
  496. };
  497.  
  498.  
  499. struct StringInfo string_drawer=
  500. {
  501.   drawer_name,        /* *Buffer */
  502.   name_backup,        /* *UndoBuffer */
  503.   0,                  /* BufferPos */
  504.   70,                 /* MaxChars (Including NULL) */
  505.   0,                  /* DispPos */
  506.  
  507.   /* Intuition initializes and maintains these variables for you: */
  508.   0,                 /* UndoPos */
  509.   0, 0,              /* CLeft, CTop */
  510.   NULL,              /* *LayerPtr */
  511.   NULL,              /* LongInt */
  512.   NULL,              /* *AltKeyMap */
  513. };
  514.  
  515.  
  516. struct Gadget gadget_drawer=
  517. {
  518.   &gadget_proportional,    /* *NextGadget */
  519.   83, 35, 198, 8,          /* LeftEdge, TopEdge, Width, Height */
  520.   GADGHCOMP,               /* Flags */
  521.   RELVERIFY,               /* Activation */
  522.   STRGADGET,               /* GadgetType */
  523.   (APTR) &border_text28s,  /* GadgetRender */
  524.   NULL,                    /* SelectRender */
  525.   &text_drawer,            /* *GadgetText */
  526.   NULL,                    /* MutualExclude */
  527.   (APTR) &string_drawer,   /* SpecialInfo */
  528.   NULL,                    /* GadgetID */
  529.   NULL                     /* UserData */
  530. };
  531.  
  532.  
  533.  
  534. /* ********************************************************************* */
  535. /* * Information for the string gadget "File:"                         * */
  536. /* ********************************************************************* */
  537.  
  538.  
  539. UBYTE file_name[FILE_LENGTH];
  540.  
  541.  
  542. /* Values for a 30-letter string box: */
  543. SHORT points30s[]=
  544. {
  545.    -7, -4,
  546.   244, -4,
  547.   244, 11,
  548.    -7, 11,
  549.    -7, -4
  550. };
  551.  
  552.  
  553. /* A border for a 30-letter string box: */
  554. struct Border border_text30s=
  555. {
  556.   0, 0,         /* LeftEdge, TopEdge */
  557.   1, 2, JAM1,   /* FrontPen, BackPen, DrawMode */
  558.   5,            /* Count */
  559.   points30s,    /* *XY */
  560.   NULL          /* *NextBorder */
  561. };
  562.  
  563.  
  564. struct IntuiText text_file=
  565. {
  566.   1, 2,     /* FrontPen, BackPen */
  567.   JAM1,     /* DrawMode */
  568.   -53, 0,   /* LewftEdge, TopEdge */
  569.   &my_font, /* *ITextFont */
  570.   "File:",  /* *IText */
  571.   NULL      /* *NextText */
  572. };
  573.  
  574.  
  575. struct StringInfo string_file=
  576. {
  577.   file_name,         /* *Buffer */
  578.   name_backup,       /* *UndoBuffer */
  579.   0,                 /* BufferPos */
  580.   40,                /* MaxChars (Including NULL) */
  581.   0,                 /* DispPos */
  582.   
  583.   /* Intuition initializes and maintains these variables for you: */
  584.   0,                 /* UndoPos */
  585.   0, 0,              /* CLeft, CTop */
  586.   NULL,              /* *LayerPtr */
  587.   NULL,              /* LongInt */
  588.   NULL,              /* *AltKeyMap */
  589. };
  590.  
  591.  
  592. struct Gadget gadget_file=
  593. {
  594.   &gadget_drawer,         /* *NextGadget */
  595.   66, 129, 240, 8,        /* LeftEdge, TopEdge, Width, Height */
  596.   GADGHCOMP,              /* Flags */
  597.   NULL,                   /* Activation */
  598.   STRGADGET,              /* GadgetType */
  599.   (APTR) &border_text30s, /* GadgetRender */
  600.   NULL,                   /* SelectRender */
  601.   &text_file,             /* *GadgetText */
  602.   NULL,                   /* MutualExclude */
  603.   (APTR) &string_file,    /* SpecialInfo */
  604.   NULL,                   /* GadgetID */
  605.   NULL                    /* UserData */
  606. };
  607.  
  608.  
  609.  
  610. /* ********************************************************************* */
  611. /* * Information for the string gadget "Extension"                     * */
  612. /* ********************************************************************* */
  613.  
  614.  
  615. UBYTE extension_name[7]; /* 7 characters including NULL. */
  616.  
  617.  
  618. /* Values for a 6-letter string box: */
  619. SHORT points6s[]=
  620. {
  621.   -7, -4,
  622.   57, -4,
  623.   57, 10,
  624.   -7, 10,
  625.   -7, -4
  626. };
  627.  
  628.  
  629. /* A border for a 6-letter string box: */
  630. struct Border border_text6s=
  631. {
  632.   0, 0,         /* LeftEdge, TopEdge */
  633.   1, 2, JAM1,   /* FrontPen, BackPen, DrawMode */
  634.   5,            /* Count */
  635.   points6s,     /* *XY */
  636.   NULL          /* *NextBorder */
  637. };
  638.  
  639.  
  640. struct IntuiText text_extension=
  641. {
  642.   1, 2,     /* FrontPen, BackPen */
  643.   JAM1,     /* DrawMode */
  644.   -45, 0,   /* LewftEdge, TopEdge */
  645.   &my_font, /* *ITextFont */
  646.   "Ext:",   /* *IText */
  647.   NULL      /* *NextText */
  648. };
  649.  
  650.  
  651. struct StringInfo string_extension=
  652. {
  653.   extension_name,    /* *Buffer */
  654.   name_backup,       /* *UndoBuffer */
  655.   0,                 /* BufferPos */
  656.   7,                 /* MaxChars (Including NULL) */
  657.   0,                 /* DispPos */
  658.   
  659.   /* Intuition initializes and maintains these variables for you: */
  660.   0,                 /* UndoPos */
  661.   0, 0,              /* CLeft, CTop */
  662.   NULL,              /* *LayerPtr */
  663.   NULL,              /* LongInt */
  664.   NULL,              /* *AltKeyMap */
  665. };
  666.  
  667.  
  668. struct Gadget gadget_extension=
  669. {
  670.   &gadget_file,             /* *NextGadget */
  671.   253, 17, 59, 8,           /* LeftEdge, TopEdge, Width, Height */
  672.   GADGHCOMP,                /* Flags */
  673.   RELVERIFY,                /* Activation */
  674.   STRGADGET,                /* GadgetType */
  675.   (APTR) &border_text6s,    /* GadgetRender */
  676.   NULL,                     /* SelectRender */
  677.   &text_extension,          /* *GadgetText */
  678.   NULL,                     /* MutualExclude */
  679.   (APTR) &string_extension, /* SpecialInfo */
  680.   NULL,                     /* GadgetID */
  681.   NULL                      /* UserData */
  682. };
  683.  
  684.  
  685.  
  686. /* ********************************************************************* */
  687. /* * Information for the boolean gadget parent "<"                     * */
  688. /* ********************************************************************* */
  689.  
  690.  
  691. /* Values for a 1-letter box: */
  692. SHORT points1[]=
  693. {
  694.    0,  0,
  695.   20,  0,
  696.   20, 15,
  697.    0, 15,
  698.    0,  0
  699. };
  700.  
  701.  
  702. /* A border for a 1-letter box: */
  703. struct Border border_text1=
  704. {
  705.   0, 0,         /* LeftEdge, TopEdge */
  706.   1, 2, JAM1,   /* FrontPen, BackPen, DrawMode */
  707.   5,            /* Count */
  708.   points1,      /* *XY */
  709.   NULL          /* *NextBorder */
  710. };
  711.  
  712.  
  713. struct IntuiText text_parent=
  714. {
  715.   1, 2,     /* FrontPen, BackPen */
  716.   JAM1,     /* DrawMode */
  717.   7,4,      /* LeftEdge, TopEdge */
  718.   &my_font, /* *ITextFont, (Topaz, 80) */
  719.   "<",      /* *IText */
  720.   NULL      /* *NextText */
  721. };
  722.  
  723.  
  724. struct Gadget gadget_parent=
  725. {
  726.   &gadget_extension,      /* *NextGadget */
  727.   290, 31, 21, 16,        /* LeftEdge, TopEdge, Width, Height */
  728.   GADGHCOMP,              /* Flags */
  729.   RELVERIFY,              /* Activation */
  730.   BOOLGADGET,             /* GadgetType */
  731.   (APTR) &border_text1,   /* GadgetRender */
  732.   NULL,                   /* SelectRender */
  733.   &text_parent,           /* *GadgetText */
  734.   NULL,                   /* MutualExclude */
  735.   NULL,                   /* SpecialInfo */
  736.   NULL,                   /* GadgetID */
  737.   NULL                    /* UserData */
  738. };
  739.  
  740.  
  741.  
  742. /* ********************************************************************* */
  743. /* * Information for the boolean gadget "dh0:"                         * */
  744. /* ********************************************************************* */
  745.  
  746.  
  747. struct IntuiText text_dh0=
  748. {
  749.   1, 2,     /* FrontPen, BackPen */
  750.   JAM1,     /* DrawMode */
  751.   7,4,      /* LeftEdge, TopEdge */
  752.   &my_font, /* *ITextFont, (Topaz, 80) */
  753.   "dh0:",   /* *IText */
  754.   NULL      /* *NextText */
  755. };
  756.  
  757.  
  758. struct Gadget gadget_dh0=
  759. {
  760.   &gadget_parent,         /* *NextGadget */
  761.   110, 13, 45, 15,        /* LeftEdge, TopEdge, Width, Height */
  762.   GADGHCOMP,              /* Flags */
  763.   RELVERIFY,              /* Activation */
  764.   BOOLGADGET,             /* GadgetType */
  765.   (APTR) &border_text4,   /* GadgetRender */
  766.   NULL,                   /* SelectRender */
  767.   &text_dh0,              /* *GadgetText */
  768.   NULL,                   /* MutualExclude */
  769.   NULL,                   /* SpecialInfo */
  770.   NULL,                   /* GadgetID */
  771.   NULL                    /* UserData */
  772. };
  773.  
  774.  
  775.  
  776. /* ********************************************************************* */
  777. /* * Information for the boolean gadget "df1:"                         * */
  778. /* ********************************************************************* */
  779.  
  780.  
  781. struct IntuiText text_df1=
  782. {
  783.   1, 2,     /* FrontPen, BackPen */
  784.   JAM1,     /* DrawMode */
  785.   7,4,      /* LeftEdge, TopEdge */
  786.   &my_font, /* *ITextFont, (Topaz, 80) */
  787.   "df1:",   /* *IText */
  788.   NULL      /* *NextText */
  789. };
  790.  
  791.  
  792. struct Gadget gadget_df1=
  793. {
  794.   &gadget_dh0,            /* *NextGadget */
  795.   59, 13, 45, 15,         /* LeftEdge, TopEdge, Width, Height */
  796.   GADGHCOMP,              /* Flags */
  797.   RELVERIFY,              /* Activation */
  798.   BOOLGADGET,             /* GadgetType */
  799.   (APTR) &border_text4,   /* GadgetRender */
  800.   NULL,                   /* SelectRender */
  801.   &text_df1,              /* *GadgetText */
  802.   NULL,                   /* MutualExclude */
  803.   NULL,                   /* SpecialInfo */
  804.   NULL,                   /* GadgetID */
  805.   NULL                    /* UserData */
  806. };
  807.  
  808.  
  809.  
  810. /* ********************************************************************* */
  811. /* * Information for the boolean gadget "df0:"                         * */
  812. /* ********************************************************************* */
  813.  
  814.  
  815. struct IntuiText text_df0=
  816. {
  817.   1, 2,     /* FrontPen, BackPen */
  818.   JAM1,     /* DrawMode */
  819.   7,4,      /* LeftEdge, TopEdge */
  820.   &my_font, /* *ITextFont, (Topaz, 80) */
  821.   "df0:",   /* *IText */
  822.   NULL      /* *NextText */
  823. };
  824.  
  825.  
  826. struct Gadget gadget_df0=
  827. {
  828.   &gadget_df1,            /* *NextGadget */
  829.   8, 13, 45, 15,          /* LeftEdge, TopEdge, Width, Height */
  830.   GADGHCOMP,              /* Flags */
  831.   RELVERIFY,              /* Activation */
  832.   BOOLGADGET,             /* GadgetType */
  833.   (APTR) &border_text4,   /* GadgetRender */
  834.   NULL,                   /* SelectRender */
  835.   &text_df0,              /* *GadgetText */
  836.   NULL,                   /* MutualExclude */
  837.   NULL,                   /* SpecialInfo */
  838.   NULL,                   /* GadgetID */
  839.   NULL                    /* UserData */
  840. };
  841.  
  842.  
  843.  
  844. /* ********************************************************************* */
  845. /* * Information for the boolean gadget "CANCEL"                       * */
  846. /* ********************************************************************* */
  847.  
  848.  
  849. struct IntuiText text_cancel=
  850. {
  851.   1, 2,     /* FrontPen, BackPen */
  852.   JAM1,     /* DrawMode */
  853.   7,4,      /* LeftEdge, TopEdge */
  854.   &my_font, /* *ITextFont, (Topaz, 80) */
  855.   "CANCEL", /* *IText */
  856.   NULL      /* *NextText */
  857. };
  858.  
  859.  
  860. struct Gadget gadget_cancel=
  861. {
  862.   &gadget_df0,            /* *NextGadget */
  863.   177, 144, 61, 15,       /* LeftEdge, TopEdge, Width, Height */
  864.   GADGHCOMP,              /* Flags */
  865.   RELVERIFY,              /* Activation */
  866.   BOOLGADGET,             /* GadgetType */
  867.   (APTR) &border_text6,   /* GadgetRender */
  868.   NULL,                   /* SelectRender */
  869.   &text_cancel,           /* *GadgetText */
  870.   NULL,                   /* MutualExclude */
  871.   NULL,                   /* SpecialInfo */
  872.   NULL,                   /* GadgetID */
  873.   NULL                    /* UserData */
  874. };
  875.  
  876.  
  877.  
  878. /* ********************************************************************* */
  879. /* * Information for the boolean gadget "DELETE"                       * */
  880. /* ********************************************************************* */
  881.  
  882.  
  883. struct IntuiText text_delete=
  884. {
  885.   1, 2,     /* FrontPen, BackPen */
  886.   JAM1,     /* DrawMode */
  887.   7,4,      /* LeftEdge, TopEdge */
  888.   &my_font, /* *ITextFont, (Topaz, 80) */
  889.   "DELETE", /* *IText */
  890.   NULL      /* *NextText */
  891. };
  892.  
  893.  
  894. struct Gadget gadget_delete=
  895. {
  896.   &gadget_cancel,         /* *NextGadget */
  897.   110, 144, 61, 15,       /* LeftEdge, TopEdge, Width, Height */
  898.   GADGHCOMP,              /* Flags */
  899.   RELVERIFY,              /* Activation */
  900.   BOOLGADGET,             /* GadgetType */
  901.   (APTR) &border_text6,   /* GadgetRender */
  902.   NULL,                   /* SelectRender */
  903.   &text_delete,           /* *GadgetText */
  904.   NULL,                   /* MutualExclude */
  905.   NULL,                   /* SpecialInfo */
  906.   NULL,                   /* GadgetID */
  907.   NULL                    /* UserData */
  908. };
  909.  
  910.  
  911.  
  912. /* ********************************************************************* */
  913. /* * Information for the boolean gadget "SAVE"                         * */
  914. /* ********************************************************************* */
  915.  
  916.  
  917. struct IntuiText text_save=
  918. {
  919.   1, 2,     /* FrontPen, BackPen */
  920.   JAM1,     /* DrawMode */
  921.   7,4,      /* LeftEdge, TopEdge */
  922.   &my_font, /* *ITextFont, (Topaz, 80) */
  923.   "SAVE",   /* *IText */
  924.   NULL      /* *NextText */
  925. };
  926.  
  927.  
  928. struct Gadget gadget_save=
  929. {
  930.   &gadget_delete,         /* *NextGadget */
  931.   59, 144, 45, 15,        /* LeftEdge, TopEdge, Width, Height */
  932.   GADGHCOMP,              /* Flags */
  933.   RELVERIFY,              /* Activation */
  934.   BOOLGADGET,             /* GadgetType */
  935.   (APTR) &border_text4,   /* GadgetRender */
  936.   NULL,                   /* SelectRender */
  937.   &text_save,             /* *GadgetText */
  938.   NULL,                   /* MutualExclude */
  939.   NULL,                   /* SpecialInfo */
  940.   NULL,                   /* GadgetID */
  941.   NULL                    /* UserData */
  942. };
  943.  
  944.  
  945.  
  946. /* ********************************************************************* */
  947. /* * Information for the boolean gadget "LOAD"                         * */
  948. /* ********************************************************************* */
  949.  
  950.  
  951. struct IntuiText text_load=
  952. {
  953.   1, 2,     /* FrontPen, BackPen */
  954.   JAM1,     /* DrawMode */
  955.   7,4,      /* LeftEdge, TopEdge */
  956.   &my_font, /* *ITextFont, (Topaz, 80) */
  957.   "LOAD",   /* *IText */
  958.   NULL      /* *NextText */
  959. };
  960.  
  961.  
  962. struct Gadget gadget_load=
  963. {
  964.   &gadget_save,           /* *NextGadget */
  965.   8, 144, 45, 15,         /* LeftEdge, TopEdge, Width, Height */
  966.   GADGHCOMP,              /* Flags */
  967.   RELVERIFY,              /* Activation */
  968.   BOOLGADGET,             /* GadgetType */
  969.   (APTR) &border_text4,   /* GadgetRender */
  970.   NULL,                   /* SelectRender */
  971.   &text_load,             /* *GadgetText */
  972.   NULL,                   /* MutualExclude */
  973.   NULL,                   /* SpecialInfo */
  974.   NULL,                   /* GadgetID */
  975.   NULL                    /* UserData */
  976. };
  977.  
  978.  
  979.  
  980. UBYTE display_text[8][34];
  981.  
  982. struct IntuiText text_list[8]=
  983. {
  984.   {
  985.     1, 0,            /* FrontPen, BackPen */
  986.     JAM2,            /* DrawMode */
  987.     0,0,             /* LeftEdge, TopEdge */
  988.     &my_font,        /* *ITextFont */
  989.     display_text[0], /* IText */
  990.     &text_list[1]    /* *NextText */
  991.   },
  992.   {
  993.     1, 0,            /* FrontPen, BackPen */
  994.     JAM2,            /* DrawMode */
  995.     0,8,             /* LeftEdge, TopEdge */
  996.     &my_font,        /* *ITextFont */
  997.     display_text[1], /* IText */
  998.     &text_list[2]    /* *NextText */
  999.   },
  1000.   {
  1001.     1, 0,            /* FrontPen, BackPen */
  1002.     JAM2,            /* DrawMode */
  1003.     0,16,            /* LeftEdge, TopEdge */
  1004.     &my_font,        /* *ITextFont */
  1005.     display_text[2], /* IText */
  1006.     &text_list[3]    /* *NextText */
  1007.   },
  1008.   {
  1009.     1, 0,            /* FrontPen, BackPen */
  1010.     JAM2,            /* DrawMode */
  1011.     0,24,            /* LeftEdge, TopEdge */
  1012.     &my_font,        /* *ITextFont */
  1013.     display_text[3], /* IText */
  1014.     &text_list[4]    /* *NextText */
  1015.   },
  1016.   {
  1017.     1, 0,            /* FrontPen, BackPen */
  1018.     JAM2,            /* DrawMode */
  1019.     0,32,            /* LeftEdge, TopEdge */
  1020.     &my_font,        /* *ITextFont */
  1021.     display_text[4], /* IText */
  1022.     &text_list[5]    /* *NextText */
  1023.   },
  1024.   {
  1025.     1, 0,            /* FrontPen, BackPen */
  1026.     JAM2,            /* DrawMode */
  1027.     0,40,            /* LeftEdge, TopEdge */
  1028.     &my_font,        /* *ITextFont */
  1029.     display_text[5], /* IText */
  1030.     &text_list[6]    /* *NextText */
  1031.   },
  1032.   {
  1033.     1, 0,            /* FrontPen, BackPen */
  1034.     JAM2,            /* DrawMode */
  1035.     0,48,            /* LeftEdge, TopEdge */
  1036.     &my_font,        /* *ITextFont */
  1037.     display_text[6], /* IText */
  1038.     &text_list[7]    /* *NextText */
  1039.   },
  1040.   {
  1041.     1, 0,            /* FrontPen, BackPen */
  1042.     JAM2,            /* DrawMode */
  1043.     0,56,            /* LeftEdge, TopEdge */
  1044.     &my_font,        /* *ITextFont */
  1045.     display_text[7], /* IText */
  1046.     NULL             /* *NextText */
  1047.   }
  1048. };
  1049.  
  1050.  
  1051.  
  1052. struct Gadget gadget_display[8]=
  1053. {
  1054.   {
  1055.     &gadget_display[1], /* *NextGadget */
  1056.     8, 50, 276, 12,     /* LeftEdge, TopEdge, Width, Height */
  1057.     GADGHNONE,          /* Flags */
  1058.     GADGIMMEDIATE,      /* Activation */
  1059.     BOOLGADGET,         /* GadgetType */
  1060.     NULL,               /* GadgetRender */
  1061.     NULL,               /* SelectRender */
  1062.     NULL,               /* *GadgetText */
  1063.     NULL,               /* MutualExclude */
  1064.     NULL,               /* SpecialInfo */
  1065.     NULL,               /* GadgetID */
  1066.     NULL                /* UserData */
  1067.   },
  1068.   {
  1069.     &gadget_display[2], /* *NextGadget */
  1070.     8, 62, 276, 8,      /* LeftEdge, TopEdge, Width, Height */
  1071.     GADGHNONE,          /* Flags */
  1072.     GADGIMMEDIATE,      /* Activation */
  1073.     BOOLGADGET,         /* GadgetType */
  1074.     NULL,               /* GadgetRender */
  1075.     NULL,               /* SelectRender */
  1076.     NULL,               /* *GadgetText */
  1077.     NULL,               /* MutualExclude */
  1078.     NULL,               /* SpecialInfo */
  1079.     NULL,               /* GadgetID */
  1080.     NULL                /* UserData */
  1081.   },
  1082.   {
  1083.     &gadget_display[3], /* *NextGadget */
  1084.     8, 70, 276, 8,      /* LeftEdge, TopEdge, Width, Height */
  1085.     GADGHNONE,          /* Flags */
  1086.     GADGIMMEDIATE,      /* Activation */
  1087.     BOOLGADGET,         /* GadgetType */
  1088.     NULL,               /* GadgetRender */
  1089.     NULL,               /* SelectRender */
  1090.     NULL,               /* *GadgetText */
  1091.     NULL,               /* MutualExclude */
  1092.     NULL,               /* SpecialInfo */
  1093.     NULL,               /* GadgetID */
  1094.     NULL                /* UserData */
  1095.   },
  1096.   {
  1097.     &gadget_display[4], /* *NextGadget */
  1098.     8, 78, 276, 8,      /* LeftEdge, TopEdge, Width, Height */
  1099.     GADGHNONE,          /* Flags */
  1100.     GADGIMMEDIATE,      /* Activation */
  1101.     BOOLGADGET,         /* GadgetType */
  1102.     NULL,               /* GadgetRender */
  1103.     NULL,               /* SelectRender */
  1104.     NULL,               /* *GadgetText */
  1105.     NULL,               /* MutualExclude */
  1106.     NULL,               /* SpecialInfo */
  1107.     NULL,               /* GadgetID */
  1108.     NULL                /* UserData */
  1109.   },
  1110.   {
  1111.     &gadget_display[5], /* *NextGadget */
  1112.     8, 86, 276, 8,      /* LeftEdge, TopEdge, Width, Height */
  1113.     GADGHNONE,          /* Flags */
  1114.     GADGIMMEDIATE,      /* Activation */
  1115.     BOOLGADGET,         /* GadgetType */
  1116.     NULL,               /* GadgetRender */
  1117.     NULL,               /* SelectRender */
  1118.     NULL,               /* *GadgetText */
  1119.     NULL,               /* MutualExclude */
  1120.     NULL,               /* SpecialInfo */
  1121.     NULL,               /* GadgetID */
  1122.     NULL                /* UserData */
  1123.   },
  1124.   {
  1125.     &gadget_display[6], /* *NextGadget */
  1126.     8, 94, 276, 8,      /* LeftEdge, TopEdge, Width, Height */
  1127.     GADGHNONE,          /* Flags */
  1128.     GADGIMMEDIATE,      /* Activation */
  1129.     BOOLGADGET,         /* GadgetType */
  1130.     NULL,               /* GadgetRender */
  1131.     NULL,               /* SelectRender */
  1132.     NULL,               /* *GadgetText */
  1133.     NULL,               /* MutualExclude */
  1134.     NULL,               /* SpecialInfo */
  1135.     NULL,               /* GadgetID */
  1136.     NULL                /* UserData */
  1137.   },
  1138.   {
  1139.     &gadget_display[7], /* *NextGadget */
  1140.     8, 102, 276, 8,      /* LeftEdge, TopEdge, Width, Height */
  1141.     GADGHNONE,          /* Flags */
  1142.     GADGIMMEDIATE,      /* Activation */
  1143.     BOOLGADGET,         /* GadgetType */
  1144.     NULL,               /* GadgetRender */
  1145.     NULL,               /* SelectRender */
  1146.     NULL,               /* *GadgetText */
  1147.     NULL,               /* MutualExclude */
  1148.     NULL,               /* SpecialInfo */
  1149.     NULL,               /* GadgetID */
  1150.     NULL                /* UserData */
  1151.   },
  1152.   {
  1153.     &gadget_load,       /* *NextGadget */
  1154.     8, 110, 276, 12,    /* LeftEdge, TopEdge, Width, Height */
  1155.     GADGHNONE,          /* Flags */
  1156.     GADGIMMEDIATE,      /* Activation */
  1157.     BOOLGADGET,         /* GadgetType */
  1158.     NULL,               /* GadgetRender */
  1159.     NULL,               /* SelectRender */
  1160.     NULL,               /* *GadgetText */
  1161.     NULL,               /* MutualExclude */
  1162.     NULL,               /* SpecialInfo */
  1163.     NULL,               /* GadgetID */
  1164.     NULL                /* UserData */
  1165.   }
  1166. };
  1167.  
  1168.  
  1169.  
  1170. /* ********************************************************************* */
  1171. /* * BIG BOX                                                           * */
  1172. /* ********************************************************************* */
  1173.  
  1174.  
  1175. /* Values for a big box: */
  1176. SHORT points_big_box[]=
  1177. {
  1178.    8, 50,
  1179.  283, 50,
  1180.  283, 121,
  1181.    8, 121,
  1182.    8, 50
  1183. };
  1184.  
  1185.  
  1186. /* A border for a 1-letter box: */
  1187. struct Border border_big_box=
  1188. {
  1189.   0, 0,           /* LeftEdge, TopEdge */
  1190.   1, 2, JAM1,     /* FrontPen, BackPen, DrawMode */
  1191.   5,              /* Count */
  1192.   points_big_box, /* *XY */
  1193.   NULL            /* *NextBorder */
  1194. };
  1195.  
  1196.  
  1197.  
  1198. /* ********************************************************************* */
  1199. /* * Information for the window                                          */
  1200. /* ********************************************************************* */
  1201.  
  1202. struct NewWindow new_file_window=
  1203. {
  1204.   0,0,              /* LeftEdge, TopEdge */
  1205.   320, 163,         /* Width, Height */
  1206.   0,1,              /* DetailPen, BlockPen */
  1207.  
  1208.   CLOSEWINDOW|      /* IDCMPFlags */
  1209.   GADGETDOWN|
  1210.   MOUSEMOVE|
  1211.   GADGETUP,
  1212.  
  1213.   ACTIVATE|         /* Flags */
  1214.   WINDOWDEPTH|
  1215.   WINDOWDRAG|
  1216.   WINDOWCLOSE|
  1217.   SMART_REFRESH,
  1218.  
  1219.   &gadget_display[0], /* *FirstGadget */
  1220.   NULL,               /* *CheckMark */
  1221.   NULL,               /* *Title */
  1222.   NULL,               /* *Screen */
  1223.   NULL,               /* *BitMap */
  1224.   0,0,                /* MinWidth, MinHeight */
  1225.   0,0,                /* MaxWidth, MaxHeight */
  1226.   WBENCHSCREEN        /* Type */
  1227. };
  1228.  
  1229.  
  1230.  
  1231.  
  1232.  
  1233.  
  1234.  
  1235.  
  1236.  
  1237.  
  1238.  
  1239.  
  1240.  
  1241.  
  1242.  
  1243. USHORT FileWindow( title, extension, x, y, screen, total_file_name )
  1244. STRPTR title;
  1245. STRPTR extension;
  1246. SHORT  x,y;
  1247. struct Screen *screen;
  1248. STRPTR total_file_name;
  1249. {
  1250.   int temp1; /* Variable used for loops etc. */
  1251.   int file_count; /* How many files/directories there are. */
  1252.  
  1253.   ULONG class;  /* Saved IntuiMessage: IDCMP flags. */
  1254.   USHORT code;  /*        -"-        : Special code. */
  1255.   APTR address; /*        -"-        : The address of the object. */
  1256.  
  1257.   int position; /* The number of the first file in the display. */
  1258.  
  1259.   BOOL working;     /* Wants the user to quit? */
  1260.   BOOL fix_display; /* Should we update the file-display? */
  1261.  
  1262.   STRPTR string_pointer; /* Pointer to a string. */
  1263.   struct file_info *pointer; /* Pointer to a file_info structure. */
  1264.  
  1265.   USHORT operation; /* What operation FileWindow will return. */
  1266.   
  1267.  
  1268.   file_lock=FALSE; /* We have not locked any file/directory. */
  1269.   more_files=FALSE; /* Do not list any files yet. */
  1270.  
  1271.  
  1272.   /* Make sure the proportional gadget is at the top, showing 100%: */
  1273.   prop_info.VertBody=0xFFFF;
  1274.   prop_info.HorizBody=0;
  1275.   prop_info.VertPot=0;
  1276.   prop_info.HorizPot=0;
  1277.   
  1278.  
  1279.   /* Copy the extension into the string gadget: */
  1280.   strcpy(extension_name, extension);
  1281.  
  1282.   /* If there is an extension, the text "Ext:" will be highlighted: */
  1283.   if(*extension_name != '\0')
  1284.     text_extension.FrontPen=3; /* Orange. (Normal WB colour) */
  1285.   else
  1286.     text_extension.FrontPen=1; /* White. (Normal WB colour) */
  1287.  
  1288.  
  1289.   /* Change some values in the new_file_window structure: */
  1290.   new_file_window.LeftEdge=x;
  1291.   new_file_window.TopEdge=y;
  1292.   new_file_window.Title=title;
  1293.  
  1294.   /* Does the user want to use on of his own screens? */
  1295.   if(screen)
  1296.   {
  1297.     new_file_window.Screen=screen;
  1298.     new_file_window.Type=CUSTOMSCREEN;
  1299.   }    
  1300.  
  1301.  
  1302.   /* Open the window: */
  1303.   if( (file_window = (struct Window *) OpenWindow(&new_file_window)) == NULL )
  1304.   {
  1305.     /* We could NOT open the window! */
  1306.   
  1307.     /* Leave: */
  1308.     return(PANIC);
  1309.   }
  1310.  
  1311.  
  1312.   /* Draw the big box around the display: */
  1313.   DrawBorder(file_window->RPort, &border_big_box, 0, 0);
  1314.  
  1315.  
  1316.  
  1317.  
  1318.   /* Allocate memory for the FileInfoBlock: */
  1319.   if((file_info=(struct FileInfoBlock *)
  1320.     AllocMem(sizeof(struct FileInfoBlock), MEMF_PUBLIC|MEMF_CLEAR))==NULL)
  1321.   {
  1322.     /* Could not allocate memory for the FileInfoBlock! */
  1323.     /* Inform the user about the problem, and leave. */
  1324.     request_ok("NOT enough memory!");
  1325.     return(PANIC);
  1326.   }
  1327.  
  1328.  
  1329.   /* Is the there anything in the total_file_name string? */
  1330.   if(*total_file_name != '\0')
  1331.   {
  1332.     /* Yes! */
  1333.     /* Try to "lock" the file/directory: */
  1334.     if((lock=Lock(total_file_name, ACCESS_READ))==NULL)
  1335.     {
  1336.       /* PROBLEMS! */
  1337.       /* File/directory/device did NOT exist! */
  1338.     }
  1339.     else
  1340.     {
  1341.       /* Could lock the file/directory! */
  1342.       file_lock=TRUE;
  1343.   
  1344.       /* Get some information of the file/directory: */
  1345.       if((Examine(lock, file_info))==NULL)
  1346.       {
  1347.         /* Could NOT examine the object! */
  1348.         request_ok("ERROR reading file/directory!");
  1349.       }
  1350.       else
  1351.       {
  1352.         /* Is it a directory or a file? */
  1353.         if(directory(file_info))
  1354.         {
  1355.           /* It is a directory! */
  1356.  
  1357.           *file_name='\0'; /* Clear file_name string. */
  1358.           /* Copy total_file_name into drawer_name string: */
  1359.           strcpy(drawer_name, total_file_name);
  1360.  
  1361.           /* Since it is a directory, we will look for more files: */
  1362.           more_files=TRUE;
  1363.         }
  1364.         else
  1365.         {
  1366.           /* It is a file! */
  1367.           
  1368.           /* Separate the file name from the path: */
  1369.           if(string_pointer=right_pos(total_file_name, '/'))
  1370.           {
  1371.             /* Copy the file name into file_name string: */
  1372.             strcpy(file_name, string_pointer+1);
  1373.             *string_pointer='\0';
  1374.           }
  1375.           else
  1376.           {
  1377.             if(string_pointer=right_pos(total_file_name, ':'))
  1378.             {
  1379.               /* Copy the file name into file_name string: */
  1380.               strcpy(file_name, string_pointer+1);
  1381.               *(string_pointer+1)='\0';
  1382.             }
  1383.             else
  1384.             {
  1385.               strcpy(file_name, total_file_name);        
  1386.               *drawer_name='\0';
  1387.               *total_file_name='\0';
  1388.             }
  1389.           }
  1390.           strcpy(drawer_name, total_file_name);
  1391.  
  1392.           /* Since it is a file, we will NOT look for more files: */
  1393.           /* However, more_files is already FALSE. */
  1394.  
  1395.         } /* Is it a directory? */
  1396.  
  1397.       } /* Could we examine the object? */
  1398.  
  1399.     } /* Could we "lock" the file/directory? */
  1400.  
  1401.   } /* Anything in the total_file_name string? */
  1402.  
  1403.  
  1404.  
  1405.  
  1406.  
  1407.  
  1408.   /* Since we have messed around with the string gadgets it is best */
  1409.   /* to adjust them so the user can see them clearly:               */
  1410.   adjust_string_gadgets();
  1411.  
  1412.  
  1413.   new_drawer(); /* Start to show us the files. */
  1414.  
  1415.  
  1416.   position=0;        /* The display will show the first file. */
  1417.   fix_display=FALSE; /* We do not need to fix the display. */
  1418.   first_file=TRUE;   /* No files saved. */
  1419.   file_count=0;      /* No files saved. */
  1420.  
  1421.  
  1422.   working=TRUE;
  1423.   do
  1424.   {
  1425.     /* If we have shown all files in the directory, we put our task */
  1426.     /* to sleep. That will speed up other programs, and we will not */
  1427.     /* use unnecessary processing time:                             */
  1428.     if(more_files==FALSE)
  1429.       Wait(1 << file_window->UserPort->mp_SigBit);
  1430.  
  1431.  
  1432.     /* Has something has happened with the gadgets in the file_window? */
  1433.     while(my_gadget_message = (struct IntuiMessage *)
  1434.       GetMsg(file_window->UserPort))
  1435.     {
  1436.       /* As long as something is happening with the gadgets we will     */
  1437.       /* stay in the while loop. This is very handy since we can        */
  1438.       /* recieve hundereds of messages if the mouse is moving, and      */
  1439.       /* we only want to update the display when the mouse has stopped: */
  1440.       
  1441.       /* Collect some interesting values: */
  1442.       class = my_gadget_message->Class;
  1443.       code = my_gadget_message->Code;
  1444.       address = my_gadget_message->IAddress;
  1445.  
  1446.       /* We have now saved some important values, and can now reply: */
  1447.       /* (Do NEVER try to get some values after you have replied!)   */
  1448.       ReplyMsg((struct Message *)my_gadget_message);
  1449.  
  1450.  
  1451.       /* What has actually happened? */
  1452.       switch(class)
  1453.       {
  1454.         case MOUSEMOVE:
  1455.           /* The proportional gadget is selected, and the mouse is  */ 
  1456.           /* moving; we must update the file_display when the mouse */
  1457.           /* has stopped: */
  1458.           fix_display=TRUE;
  1459.           break;
  1460.  
  1461.         case CLOSEWINDOW:
  1462.           /* The user wants to quit. */
  1463.           connect_dir_file(total_file_name);
  1464.           working=FALSE;
  1465.           operation=QUIT;
  1466.           break;
  1467.  
  1468.         case GADGETDOWN:
  1469.            /* A gadget has been pressed down. */
  1470.            /* Which gadget has been clicked on? */
  1471.            
  1472.            /* DISPLAY */
  1473.            /* Is the user clicking inside the file display? */
  1474.            for(temp1=0; temp1 < 8; temp1++)
  1475.            {
  1476.              if(address == (APTR)&gadget_display[temp1])
  1477.              {
  1478.                /* The user wants to select a file/directory: */
  1479.                pick_file(temp1+position);
  1480.              }
  1481.            }
  1482.            break;
  1483.  
  1484.  
  1485.  
  1486.         case GADGETUP:
  1487.            /* A gadget has been released. */
  1488.            /* Which gadget has been clicked on? */
  1489.  
  1490.  
  1491.            /* LOAD */
  1492.            if(address == (APTR)&gadget_load)
  1493.            {
  1494.              if(last_check(total_file_name))
  1495.              {
  1496.                working=FALSE;
  1497.                operation=LOAD;
  1498.              }
  1499.              break;
  1500.            }
  1501.  
  1502.  
  1503.            /* SAVE */
  1504.            if(address == (APTR)&gadget_save)
  1505.            {
  1506.              if(last_check(total_file_name))
  1507.              {
  1508.                working=FALSE;
  1509.                operation=SAVE;
  1510.              }
  1511.              break;
  1512.            }
  1513.  
  1514.  
  1515.            /* DELETE */
  1516.            if(address == (APTR)&gadget_delete)
  1517.            {
  1518.              delete_file_dir(total_file_name);
  1519.              break;
  1520.            }
  1521.  
  1522.  
  1523.            /* CANCEL */
  1524.            if(address == (APTR)&gadget_cancel)
  1525.            {
  1526.              connect_dir_file(total_file_name);
  1527.              working=FALSE;
  1528.              operation=CANCEL;
  1529.              break;
  1530.            }
  1531.  
  1532.  
  1533.            /* df0: */
  1534.            if(address == (APTR)&gadget_df0)
  1535.            {
  1536.              change_device("df0:");
  1537.              break;
  1538.            }
  1539.  
  1540.  
  1541.            /* df1: */
  1542.            if(address == (APTR)&gadget_df1)
  1543.            {
  1544.              change_device("df1:");
  1545.              break;
  1546.            }
  1547.  
  1548.  
  1549.            /* dh0: */
  1550.            if(address == (APTR)&gadget_dh0)
  1551.            {
  1552.              change_device("dh0:");
  1553.              break;
  1554.            }
  1555.  
  1556.  
  1557.            /* DRAWER: */
  1558.            if(address == (APTR)&gadget_drawer)
  1559.            {
  1560.              /* The user has entered something new in the drawer: */
  1561.              new_drawer();
  1562.              break;
  1563.            }
  1564.  
  1565.  
  1566.            /* EXTENSION: */
  1567.            if(address == (APTR)&gadget_extension)
  1568.            {
  1569.              /* If there is an extension, the text "Ext:" will be */
  1570.              /* highlighted: */
  1571.              if(*extension_name != '\0')
  1572.                text_extension.FrontPen=3; /* Orange. (Normal WB colour) */
  1573.              else
  1574.                text_extension.FrontPen=1; /* White. (Normal WB colour) */
  1575.  
  1576.              /* Show the user the colour change: */
  1577.              RefreshGadgets(&gadget_extension, file_window, NULL);
  1578.  
  1579.              /* Start again to diplay the files, using a new extension. */
  1580.              new_drawer();
  1581.              break;
  1582.            }
  1583.  
  1584.  
  1585.            /* PARENT: "<" */
  1586.            if(address == (APTR)&gadget_parent)
  1587.            {
  1588.              parent();
  1589.              break;
  1590.            }
  1591.  
  1592.  
  1593.            /* PROPORTIONAL */
  1594.            if(address == (APTR)&gadget_proportional)
  1595.            {
  1596.              /* The user has released the proprtional gadget, update */
  1597.              /* the display: */
  1598.              fix_display=TRUE;
  1599.              break;
  1600.            }
  1601.       }
  1602.     }
  1603.  
  1604.  
  1605.     /* Do we need to update the file display? */
  1606.     if(fix_display)
  1607.     {
  1608.       fix_display=FALSE;
  1609.  
  1610.       /* Which file should we start to show in the display? */
  1611.       if(file_count > 8)
  1612.         position=(int) prop_info.VertPot/(float) 0xFFFF*(file_count-8);
  1613.       else
  1614.         position=0;
  1615.  
  1616.       /* List the files: (Starting with position) */
  1617.       display_list(position);
  1618.     }
  1619.  
  1620.  
  1621.     if(more_files)
  1622.     {
  1623.       /* Are there more files/dirtectories left to be collected? */    
  1624.       if(ExNext(lock, file_info))
  1625.       {
  1626.         /* List the file/directory if it is: */
  1627.         /* 1. A file which has the right extension. */
  1628.         /* 2. A directory. */
  1629.         if(stricmp(extension_name, (file_info->fib_FileName+
  1630.            strlen(file_info->fib_FileName)-strlen(extension_name)))==0 ||
  1631.            directory(file_info) )
  1632.         {
  1633.           /* Is this the first file/directory? */
  1634.           if(first_file)
  1635.           {
  1636.             /* first_pointer will point at the first file in our list: */
  1637.             first_pointer=(struct file_info *) save_file_info(file_info);
  1638.             
  1639.             if(first_pointer != NULL)
  1640.             {
  1641.               /* There are no more elements (for the moment) in our list: */ 
  1642.               first_pointer->next=NULL; 
  1643.               first_file=FALSE;
  1644.             }
  1645.             file_count=1;
  1646.             position=1;
  1647.           }
  1648.           else
  1649.           {
  1650.             /* save_file_info will return a pointer to the allocated */
  1651.             /* structure: */
  1652.             pointer=(struct file_info *) save_file_info(file_info);
  1653.             
  1654.             /* If we have been able to allocate space for the file we */
  1655.             /* put it into our list: */
  1656.             if(pointer !=NULL)
  1657.             {
  1658.               /* Put the new structure into the list: */
  1659.               put_in(first_pointer, pointer);       
  1660.               file_count++;
  1661.             }
  1662.           }
  1663.         
  1664.           /* If tehre are more than eight files/directories we modify */
  1665.           /* the proportional gadget: */
  1666.           if(file_count > 8)
  1667.           {
  1668.             ModifyProp
  1669.             (
  1670.               &gadget_proportional,       /* PropGadget */
  1671.               file_window,                /* Pointer */
  1672.               NULL,                       /* Requester */
  1673.               prop_info.Flags,            /* Flags */
  1674.               0,                          /* HorizPot */
  1675.               prop_info.VertPot,          /* VertPot */
  1676.               0,                          /* HorizBody */
  1677.               (ULONG) 0xFFFF*8/file_count /* VerBody */
  1678.             );            
  1679.             position=(int) prop_info.VertPot/(float) 0xFFFF*(file_count-8);
  1680.           }
  1681.           else
  1682.            position=0;
  1683.  
  1684.  
  1685.           /* List all the files: */
  1686.           display_list(position);
  1687.         }
  1688.       }
  1689.       else
  1690.       {
  1691.         /* ExNext() failed: */
  1692.         
  1693.         more_files=FALSE; /* Do not try to list any more files. */
  1694.  
  1695.         /* Check what went wrong: */
  1696.         /* If the error message is NOT "ERROR_NO_MORE_ENTRIES" something */
  1697.         /* went terrible wrong while reading: */
  1698.         if(IoErr() != ERROR_NO_MORE_ENTRIES)
  1699.         {
  1700.           request_ok("ERROR reading file/directory!");
  1701.         }
  1702.       }
  1703.     }
  1704.   } while(working);
  1705.  
  1706.   /* Clean up and leave: */
  1707.  
  1708.  
  1709.   /* This will clear the IDCMP port: */
  1710.   while( (my_gadget_message = (struct IntuiMessage *)
  1711.            GetMsg(file_window->UserPort)) )
  1712.   {
  1713.     ReplyMsg((struct Message *)my_gadget_message);
  1714.   }
  1715.  
  1716.  
  1717.   /* Deallocate the memory we have dynamically allocated: */ 
  1718.   deallocate_file_info();
  1719.  
  1720.  
  1721.   /* If we have "locked" a file/directory, "unlock" it: */
  1722.   if(file_lock)
  1723.   {
  1724.     UnLock(lock);
  1725.     file_lock=FALSE;
  1726.   }
  1727.   
  1728.   
  1729.   /* Deallocate FileInfoBlock: */
  1730.   if(file_info) FreeMem(file_info, sizeof(struct FileInfoBlock));
  1731.  
  1732.  
  1733.   /* If we have successfully opened the file_window, we close it: */
  1734.   if(file_window)
  1735.     CloseWindow(file_window);
  1736.   
  1737.   /* Leave with a message: */
  1738.   return(operation);
  1739. }
  1740.  
  1741.  
  1742.  
  1743. /* Deallocate the memory we have dynamically allocated: */ 
  1744. void deallocate_file_info()
  1745. {
  1746.   struct file_info *pointer, *temp_pointer;
  1747.  
  1748.   /* Does the first pointer point to an allocated structure? */   
  1749.   if(first_pointer)
  1750.   {
  1751.     /* Save the address of the next structure: */
  1752.     pointer=first_pointer->next;
  1753.     
  1754.     /* Deallocate the first structure: */
  1755.     FreeMem( first_pointer, sizeof(struct file_info));
  1756.  
  1757.     /* As long as pointer points to an allocated structure: */
  1758.     while(pointer)
  1759.     {
  1760.       /* Save the address of the next structure: */    
  1761.       temp_pointer=pointer->next;
  1762.       
  1763.       FreeMem( pointer, sizeof(struct file_info));
  1764.       pointer=temp_pointer;
  1765.     }
  1766.   }
  1767.   
  1768.   /* Clear first_pointer: */
  1769.   first_pointer=NULL;
  1770.  
  1771.   /* Next time we try to list the files, we start with the first_file: */
  1772.   first_file=TRUE;
  1773. }
  1774.  
  1775.  
  1776.  
  1777. /* Allocate memory for the new file/directory, and fills the structure */
  1778. /* with information. (name of the object, and if it is a directory.)   */
  1779. /* Returns a memory pointer to the allocated structure, or NULL.       */
  1780. APTR save_file_info(info)
  1781. struct FileInfoBlock *info;
  1782. {
  1783.   struct file_info *pointer;
  1784.  
  1785.   if((pointer=(struct file_info *)
  1786.     AllocMem(sizeof(struct file_info), MEMF_PUBLIC|MEMF_CLEAR))==NULL)
  1787.   {
  1788.     /* We could NOT allocate memory for the structure! */
  1789.     request_ok("NOT enough memory!"); /* Inform the user. */
  1790.     more_files=FALSE; /* Do not list any more files/directories. */
  1791.     return(NULL);
  1792.   }
  1793.   else
  1794.   {
  1795.     /* If the file/directory name is not too long, we copy it into the */
  1796.     /* new stucture: */
  1797.     if(strlen(info->fib_FileName) < 28)
  1798.       strcpy(pointer->name, info->fib_FileName);
  1799.     else
  1800.     {
  1801.       /* The file/directory name is too long! */
  1802.       /* Inform the user: */
  1803.       
  1804.       if( directory(info))
  1805.         request_ok("Directory name too long!"); /* It is a directory. */
  1806.       else    
  1807.         request_ok("File name too long!"); /* It is a file. */
  1808.  
  1809.       /* Deallocate the structure: */
  1810.       FreeMem( pointer, sizeof(struct file_info));
  1811.       return(NULL);
  1812.     }
  1813.  
  1814.     /* Is it a file or a directory? */
  1815.     if( directory(info))
  1816.       pointer->directory=TRUE; /* It is a directory. */
  1817.     else    
  1818.       pointer->directory=FALSE; /* It is a file. */
  1819.   }
  1820.   
  1821.   /* Return the address of the allocated structure: */
  1822.   return( (APTR) pointer);
  1823. }
  1824.  
  1825.  
  1826.  
  1827. /* Will check a FileInfoBlock if it is a file or a directory. */
  1828. /* Return TRUE if it is a directory, FALSE if it is a file.   */
  1829. BOOL directory(info)
  1830. struct FileInfoBlock *info;
  1831. {
  1832.   if(info->fib_DirEntryType < 0)
  1833.     return(FALSE);
  1834.   else
  1835.     return(TRUE);
  1836. }
  1837.  
  1838.  
  1839.  
  1840. /* Put the new structure into the dynamically allocated list at the */
  1841. /* right place (sorted alphabetically, directories first):          */
  1842. void put_in(a_pointer, pointer)
  1843. struct file_info *a_pointer, *pointer;
  1844. {
  1845.   struct file_info *old_pointer=NULL;
  1846.  
  1847.   /* Move slowly down the list and try to fit in the structure: */
  1848.   while( a_pointer && file_comp(a_pointer->name, pointer->name) )
  1849.   {
  1850.     old_pointer=a_pointer;
  1851.     a_pointer=a_pointer->next;
  1852.   }
  1853.  
  1854.   if(a_pointer)
  1855.   {
  1856.     if(old_pointer)
  1857.     {
  1858.       /* Put the structure into the list: */
  1859.       pointer->next=old_pointer->next;
  1860.       old_pointer->next=pointer;
  1861.     }
  1862.     else
  1863.     {
  1864.       /* First in the list! */
  1865.       pointer->next=first_pointer;
  1866.       first_pointer=pointer;
  1867.     }
  1868.   }
  1869.   else
  1870.   {
  1871.     /* Last int the list: */
  1872.     old_pointer->next=pointer;
  1873.     pointer->next=NULL;
  1874.   }
  1875. }
  1876.  
  1877.  
  1878.  
  1879. /* This function will return TRUE if the first pointer (a_pointer) */
  1880. /* points to a file structure which should come before the second  */
  1881. /* pointers file structure.                                        */
  1882. /* ORDER: */
  1883. /* 1. DIRECTORIES sorted alphabetically. */
  1884. /* 2. FILES       sorted alphabetically. */
  1885.  
  1886. BOOL file_comp(a_pointer, pointer)
  1887. struct file_info *a_pointer, *pointer;
  1888. {
  1889.   if(a_pointer->directory == FALSE && pointer->directory)
  1890.     return(FALSE);
  1891.     
  1892.   if(a_pointer->directory == pointer->directory)
  1893.   {
  1894.     if(stricmp(a_pointer->name, pointer->name) <= 0 )
  1895.       return(TRUE);
  1896.     else
  1897.       return(FALSE);
  1898.   } 
  1899.   return(TRUE);
  1900. }
  1901.  
  1902.  
  1903.  
  1904. /* Give this function a string and a character, and it will return a */
  1905. /* pointer to the right most occurance character in you string which */
  1906. /* match your character.                                             */
  1907. STRPTR right_pos(string, sign)
  1908. STRPTR string;
  1909. char sign;
  1910. {
  1911.   STRPTR start_pos;
  1912.   
  1913.   start_pos=string;
  1914.   
  1915.   /* Go to the end: */
  1916.   while(*string != '\0')
  1917.     string++;
  1918.  
  1919.   /* Start to go backwards and check teh string: */
  1920.   while(*string != sign && string > start_pos)
  1921.     string--;
  1922.     
  1923.   if(*string==sign)
  1924.     return(string); /* We have found a matching character. */
  1925.  
  1926.   return(NULL); /* We could not find a matching character. */
  1927. }
  1928.  
  1929.  
  1930.  
  1931. /* This function will change to a new device, for example df0:. */
  1932. /* Does not return anything.                                    */
  1933. void change_device(device)
  1934. STRPTR device;
  1935. {
  1936.   strcpy(drawer_name, device); /* Change the drawer string. */
  1937.  
  1938.   adjust_string_gadgets(); /* Adjust the string gadgets. */
  1939.  
  1940.   new_drawer(); /* Start to show us the new files/directories */
  1941. }
  1942.  
  1943.  
  1944.  
  1945. /* When the user or the program has changet the drawer string, this      */
  1946. /* function is called, and will do what is necessary to start to collect */
  1947. /* the new files/directories from the disk.                              */
  1948. /* Returns TRUE if everything is OK, and FALSE if something went wrong.  */
  1949. BOOL new_drawer()
  1950. {
  1951.   STRPTR string_pointer;
  1952.  
  1953.   /* Unlock: */
  1954.   if(file_lock)
  1955.   {
  1956.     UnLock(lock);
  1957.     file_lock=FALSE;
  1958.   }
  1959.  
  1960.   /* Deallocate the memory we have dynamically allocated: */ 
  1961.   deallocate_file_info();
  1962.  
  1963.   /* Change the proportianal gadget: */
  1964.   ModifyProp
  1965.   (
  1966.     &gadget_proportional, /* PropGadget */
  1967.     file_window,          /* Pointer */
  1968.     NULL,                 /* Requester */
  1969.     prop_info.Flags,      /* Flags */
  1970.     0,                    /* HorizPot */
  1971.     0,                    /* VertPot */
  1972.     0,                    /* HorizBody */
  1973.     (ULONG) 0xFFFF        /* VerBody */
  1974.   );
  1975.  
  1976.   /* Clear the display: */
  1977.   display_list(0);
  1978.  
  1979.   more_files=FALSE;
  1980.  
  1981.   /* Try to "lock" the file/directory: */
  1982.   if((lock=Lock(drawer_name, ACCESS_READ))==NULL)
  1983.   {
  1984.     /* We could NOT lock the file/directory/device! */
  1985.     /* Inform the user: */
  1986.     string_pointer=drawer_name+strlen(drawer_name)-1;
  1987.     if(*string_pointer==':')
  1988.       request_ok("Device NOT found!");
  1989.     else
  1990.       request_ok("Device/Directory NOT found!");
  1991.  
  1992.     return(FALSE); /* ERROR */
  1993.   }
  1994.   else
  1995.   {
  1996.     /* We "locked" the file/directory! */
  1997.     file_lock=TRUE;
  1998.   }
  1999.  
  2000.   /* Now try to get some information from the file/directory: */
  2001.   if((Examine(lock, file_info))==NULL)
  2002.   {
  2003.     /* We could NOT examine the file/directory! */
  2004.  
  2005.     request_ok("ERROR reading file/directory!"); /* Inform the user. */
  2006.  
  2007.     return(FALSE); /* ERROR */
  2008.   }
  2009.  
  2010.   /* Is it a directory or a file? */
  2011.   if(directory(file_info))
  2012.   {
  2013.     /* It is a directory! */
  2014.  
  2015.     /* Since it is a directory, we will look for more files: */
  2016.     more_files=TRUE;
  2017.   }
  2018.   else
  2019.   {
  2020.     /* It is a file! */
  2021.     request_ok("NOT a valid directory name!"); /* Inform the user. */
  2022.     return(FALSE);
  2023.   }  
  2024.   return(TRUE);
  2025. }
  2026.  
  2027.  
  2028.  
  2029. /* The function parent() will try to go backwards one step in the */
  2030. /* directory path.                                                */
  2031. /* Does not return anything.                                      */
  2032. void parent()
  2033. {
  2034.   STRPTR string_pointer;
  2035.  
  2036.   /* Separate the last directory from the path: */
  2037.   if(string_pointer=right_pos(drawer_name, '/'))
  2038.   {
  2039.     /* Take away the last directory: */
  2040.     *string_pointer='\0';
  2041.   }
  2042.   else
  2043.   {
  2044.     if(string_pointer=right_pos(drawer_name, ':'))
  2045.     {
  2046.       /* Take away the last directory: */
  2047.       /* Only the device ("df0:" for example) left: */
  2048.       *(string_pointer+1)='\0';
  2049.     }
  2050.     else
  2051.     {
  2052.       /* Strange drawer_name, clear it: */
  2053.       *drawer_name='\0';
  2054.     }
  2055.   }
  2056.  
  2057.   /* Since we have messed around with the string gadgets, adjust them: */
  2058.   adjust_string_gadgets();
  2059.   
  2060.   /* Start to show the user the files etc in the new directory: */
  2061.   new_drawer();
  2062. }
  2063.  
  2064.  
  2065.  
  2066. /* You give this function a pointer to an error string, and it will open */
  2067. /* a simple requester displaying the message. The requester will go away */
  2068. /* first when the user has selected the button "OK".                     */
  2069. /* Does not return anything.                                             */
  2070. void request_ok(message)
  2071. STRPTR message;
  2072. {
  2073.   text_request.IText=message;
  2074.   
  2075.   AutoRequest
  2076.   (
  2077.     file_window,   /* Window */
  2078.     &text_request, /* BodyText */
  2079.     NULL,          /* PositiveText nothing */
  2080.     &ok_request,   /* NegativeText OK */
  2081.     NULL,          /* PositiveFlags */
  2082.     NULL,          /* NegativeFlags */
  2083.     320,           /* Width */
  2084.     72             /* Height */
  2085.   );
  2086. }
  2087.  
  2088.  
  2089.  
  2090. /* This function will also open a simple requester, but will instead      */
  2091. /* ask the user to make a choice between option1 or option2               */
  2092. /* If the user selects option1 the function returns TRUE, else it returns */
  2093. /* FALSE.                                                                 */
  2094. BOOL request_ask(message, option1, option2)
  2095. STRPTR message, option1, option2;
  2096. {
  2097.   text_request.IText=message;
  2098.   option1_request.IText=option1;
  2099.   option2_request.IText=option2;
  2100.   
  2101.   
  2102.   return( (BOOL) AutoRequest
  2103.   (
  2104.     file_window,       /* Window */
  2105.     &text_request,     /* BodyText */
  2106.     &option1_request,  /* PositiveText, TRUE */
  2107.     &option2_request,  /* NegativeText, FALSE */
  2108.     NULL,              /* PositiveFlags */
  2109.     NULL,              /* NegativeFlags */
  2110.     320,               /* Width */
  2111.     72                 /* Height */
  2112.   ));
  2113. }
  2114.  
  2115.  
  2116.  
  2117. /* This function will display the files etc which are inside the */
  2118. /* directory, starting with the file number start_pos.           */
  2119. /* Does not return anything.                                     */
  2120. void display_list(start_pos)
  2121. int start_pos;
  2122. {
  2123.   struct file_info *pointer;
  2124.   int pos, temp1;
  2125.                   /* 123456789012345678901234567890123 */
  2126.   char empty_name[]="                                 ";
  2127.   STRPTR string_pointer;
  2128.   BOOL clear;
  2129.   
  2130.   pos=0;
  2131.   
  2132.   /* Does it exist any files at all? */
  2133.   if(first_pointer)
  2134.   {
  2135.     pointer=first_pointer;
  2136.  
  2137.     /* Go through the list until you have found the file/directory */
  2138.     /* which should be shown first:                                */
  2139.     while(pointer && pos < start_pos)
  2140.     {
  2141.       pos++;
  2142.       pointer=pointer->next;
  2143.     }
  2144.     
  2145.     /* Try to show the eight files: */
  2146.     pos=0;
  2147.     while(pointer && pos < 8)
  2148.     {
  2149.       strcpy(display_text[pos], pointer->name);
  2150.       
  2151.       clear=FALSE;
  2152.       temp1=0;
  2153.       string_pointer=display_text[pos];
  2154.  
  2155.       if(pointer->directory)
  2156.       {
  2157.         /* It is a directory: */
  2158.         text_list[pos].FrontPen=3; /* Highlight it. */
  2159.  
  2160.         /* Clear everything after the name, and add the string "(Dir)". */
  2161.         while(temp1 < 28)
  2162.         {
  2163.           if(*string_pointer=='\0')
  2164.             clear=TRUE;
  2165.           if(clear)
  2166.             *string_pointer=' ';
  2167.           string_pointer++;
  2168.           temp1++;
  2169.         }
  2170.         *string_pointer='\0';
  2171.         strcat(display_text[pos], "(Dir)");
  2172.       }
  2173.       else
  2174.       {
  2175.         /* It is a file: */
  2176.         text_list[pos].FrontPen=1; /* Normal colour. */
  2177.  
  2178.         /* Clear everything after the name: */
  2179.         while(temp1 < 33)
  2180.         {
  2181.           if(*string_pointer=='\0')
  2182.             clear=TRUE;
  2183.           if(clear)
  2184.             *string_pointer=' ';
  2185.           string_pointer++;
  2186.           temp1++;
  2187.         }
  2188.         *string_pointer='\0';
  2189.       }      
  2190.       pos++;
  2191.       pointer=pointer->next; /* Next. */
  2192.     }
  2193.   }
  2194.  
  2195.   /* If there are less than eight files, show clear the rest of the */
  2196.   /* display: */
  2197.   while(pos < 8)
  2198.   {
  2199.     strcpy(display_text[pos], empty_name);
  2200.     pos++;
  2201.   }
  2202.   
  2203.   /* Show the user the new display: */
  2204.   PrintIText(file_window->RPort, text_list, 13+3, 53+1);
  2205. }
  2206.  
  2207.  
  2208.  
  2209. /* The user has selected a file or a directory. If it is a file put it */
  2210. /* into the file string, otherwise put it into the drawer string.      */
  2211. /* Returns TRUE if everything went OK, FALSE if there was a problem.   */
  2212. BOOL pick_file(file_pos)
  2213. int file_pos;
  2214. {
  2215.   struct file_info *pointer=NULL;
  2216.   STRPTR string_pointer;
  2217.   int pos=0;
  2218.   
  2219.   /* Go through the allocated list untill we find the file/directory: */
  2220.   if(first_pointer)
  2221.   {
  2222.     pointer=first_pointer;
  2223.     
  2224.     while(pointer && pos < file_pos)
  2225.     {
  2226.       pos++;
  2227.       pointer=pointer->next;
  2228.     }
  2229.   }
  2230.  
  2231.   /* Have we found the file/directory? */
  2232.   if(pointer)
  2233.   {
  2234.     if(pointer->directory)
  2235.     {
  2236.       /* It is a directory! */
  2237.       
  2238.       /* Is the drawer_name string long enough? */
  2239.       /* (+2: 1 for the NULL ('\0') character, 1 for the '\' character) */
  2240.       if((strlen(pointer->name)+strlen(drawer_name)+2) <= DRAWER_LENGTH)
  2241.       {
  2242.         /* YES!, there is enough room for it. */
  2243.         string_pointer=drawer_name+strlen(drawer_name)-1;
  2244.         if(*string_pointer==':'  || *string_pointer=='\0' )
  2245.           strcat(drawer_name, pointer->name);
  2246.         else
  2247.         {
  2248.           /* We need to add a '/' before we can add the directory. */
  2249.           strcat(drawer_name, "/");
  2250.           strcat(drawer_name, pointer->name);
  2251.         }
  2252.         
  2253.         /* Adjust the string gadgets: */
  2254.         adjust_string_gadgets();
  2255.       }
  2256.       else
  2257.       {
  2258.         /* The drawer_name is NOT big enough! */
  2259.         request_ok("Too long drawer string"); /* Inform the user. */
  2260.         return(FALSE); /* ERROR */
  2261.       }
  2262.       new_drawer();
  2263.       return(TRUE); /* OK */
  2264.     }
  2265.     else
  2266.     {
  2267.       /* It is a File! */
  2268.       /* Is the file_name string long enough? */
  2269.       /* (+1 for the NULL ('\0') character.) */
  2270.       if((strlen(pointer->name)+1) <= FILE_LENGTH)
  2271.       {
  2272.         strcpy(file_name, pointer->name);
  2273.         adjust_string_gadgets();
  2274.       }
  2275.       else
  2276.       {
  2277.         /* The file_name is NOT big enough! */
  2278.         request_ok("File name too long!"); /* Inform the user. */
  2279.         return(FALSE); /* ERROR */
  2280.       }
  2281.       return(TRUE); /* OK */
  2282.     }
  2283.   }
  2284. }
  2285.  
  2286.  
  2287.  
  2288. /* Adjust the string gadgets, so the user can */
  2289. /* at least see the last 28/22 characters.    */
  2290. /* Does not return anything.                  */
  2291. void adjust_string_gadgets()
  2292. {
  2293.   int length;
  2294.  
  2295.   length=strlen(file_name);        
  2296.  
  2297.   if(length > 28)
  2298.     string_file.DispPos=length-28;
  2299.   else
  2300.     string_file.DispPos=0;
  2301.  
  2302.   string_file.BufferPos=string_file.DispPos;
  2303.   
  2304.  
  2305.   length=strlen(drawer_name);        
  2306.  
  2307.   if(length > 22)
  2308.     string_drawer.DispPos=length-22;
  2309.   else
  2310.     string_drawer.DispPos=0;
  2311.  
  2312.   string_drawer.BufferPos=string_drawer.DispPos;
  2313.  
  2314.   /* Display the changes. */
  2315.   RefreshGadgets(&gadget_file, file_window, NULL);
  2316. }
  2317.  
  2318.  
  2319.  
  2320. /* Returns TRUE if there exist a file name, otherwise FALSE. */
  2321. BOOL last_check(name)
  2322. STRPTR name;
  2323. {
  2324.   if(*file_name == '\0')
  2325.   {
  2326.     /* No file name! */
  2327.     request_ok("NO filename selected!"); /* Inform the user. */
  2328.     return(FALSE);
  2329.   }
  2330.   else
  2331.   {
  2332.     /* Change the total_file_name. Drawer + File. */
  2333.     connect_dir_file(name);
  2334.   }
  2335.   return(TRUE);
  2336. }
  2337.  
  2338.  
  2339.  
  2340. /* This function will connect the drawer string with the file string. */
  2341. /* Does not return anything.                                          */
  2342. void connect_dir_file(name)
  2343. STRPTR name;
  2344. {
  2345.   STRPTR string_pointer;
  2346.   
  2347.        
  2348.   strcpy(name, drawer_name); /* Copy the drawer string into name. */
  2349.  
  2350.   /* Does it exist a file name? */
  2351.   if(*file_name != '\0')
  2352.   {
  2353.     /* Yes! */
  2354.     string_pointer=drawer_name+strlen(drawer_name)-1;
  2355.     if(*string_pointer==':'  || *string_pointer=='\0' )
  2356.     {
  2357.       strcat(name, file_name); /* Add the file name. */
  2358.     }
  2359.     else
  2360.     {
  2361.       strcat(name, "/"); /* Add a '\'. */
  2362.       strcat(name, file_name); /* Add the file name. */
  2363.     }
  2364.   }
  2365. }
  2366.  
  2367.  
  2368.  
  2369. /* Does not return anything. */
  2370. void delete_file_dir(total_file_name)
  2371. STRPTR total_file_name;
  2372. {
  2373.   BOOL delete_it;
  2374.  
  2375.   /* Presume the user do not want to deleta the file/dir: */
  2376.   delete_it=FALSE;
  2377.   
  2378.   if(*file_name == '\0' && *drawer_name != '\0')
  2379.   {
  2380.     /* There is no filename string, but there is something */
  2381.     /* in the drawer string. The user wants to delete a */
  2382.     /* directory: */
  2383.                  
  2384.     /* Is it a device or a directory? */
  2385.     if( *(drawer_name+strlen(drawer_name)-1) ==':')
  2386.     {
  2387.       /* The user wants to delete a device: */
  2388.       /* Not a very good idea! */
  2389.       request_ok("You can NOT delete a device!");
  2390.     }
  2391.     else
  2392.     {
  2393.       /* The user wants to delete a directory: */
  2394.                    
  2395.       /* However, it is important to check that the user */
  2396.       /* realy wants to delete it:                       */
  2397.       delete_it=request_ask("OK to delete directory?","DELETE","CANCEL");
  2398.                    
  2399.       if(delete_it)
  2400.       {
  2401.         /* YES! The user wanted to delete the directory.  */
  2402.         /* Before we try to delete it we must "unlock" it */
  2403.         if(file_lock)
  2404.         {
  2405.           UnLock(lock);
  2406.           file_lock=FALSE;
  2407.         }
  2408.       }
  2409.     }
  2410.   }
  2411.   else
  2412.   {
  2413.     if(*file_name != '\0')
  2414.     {
  2415.       /* There is something in the file_name string. The user */
  2416.       /* wants to delete a file: */
  2417.       
  2418.       /* We will here again give the user a last chance to */
  2419.       /* make up his/her mind: */
  2420.       delete_it=request_ask("OK to delete file?","DELETE","CANCEL");
  2421.     }
  2422.     else
  2423.     {
  2424.       /* Nothing in the drawer string, nor in the file string. */
  2425.       /* The user wants to delete something, but has NOT       */
  2426.       /* declared which file/directory he/she wants to delete: */
  2427.       request_ok("NO file/directory selected!");
  2428.     }
  2429.   }
  2430.   
  2431.   /* Should we delete the file/directory? */
  2432.   if(delete_it)
  2433.   {
  2434.     /* Yes! */
  2435.     
  2436.     /* Put the drawer name together with the file name: */
  2437.     connect_dir_file(total_file_name);
  2438.     
  2439.     /* We try to delete the file/directory: */
  2440.     if(DeleteFile(total_file_name))
  2441.     {
  2442.       /* We have deleted the file/directory successfully: */
  2443.               if(*file_name != '\0')
  2444.       {
  2445.         /* A file was deleted: */
  2446.         *file_name='\0'; /* Take away the file name. */
  2447.         adjust_string_gadgets(); /* Adjust the string gadgets. */
  2448.         new_drawer(); /* Show the user the remaining files. */
  2449.       }
  2450.       else
  2451.       {
  2452.         /* A directory was deleted: */
  2453.         parent(); /* Go back one directory. */  
  2454.       }
  2455.     }
  2456.     else
  2457.     {
  2458.       /* Something went wrong: */
  2459.       if(*file_name != '\0')
  2460.         request_ok("Could NOT delete the file!");
  2461.       else
  2462.         request_ok("Could NOT delete directory!");
  2463.       
  2464.       /* Since we have unlocked the directory/file we have */
  2465.       /* to lock it again, and clean up the display: */
  2466.       new_drawer();
  2467.     }
  2468.   }
  2469. }
  2470.  
  2471. /* THE END */
  2472.  
  2473.